package com.wondream.myframework.app.common.apollo;

import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.enums.PropertyChangeType;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import javafx.util.Pair;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.core.env.Environment;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;

/**
 *
 */
@Slf4j
public class CfssAutoUpdateConfigChangeListener implements ConfigChangeListener {

    private final Environment environment;

    public CfssAutoUpdateConfigChangeListener(Environment environment) {
        this.environment = environment;
    }

    /**
     * 接受apollo值变化事件，更新对应的ConfigProperty类
     */
    @Override
    public void onChange(ConfigChangeEvent configChangeEvent) {
        Set<String> changedKeys = configChangeEvent.changedKeys();
        if (CollectionUtils.isEmpty(changedKeys)) {
            return;
        }
        changedKeys.forEach(key -> {
            // 1.获取改变的键值对
            Collection<Pair<String, Object>> targetValues = CfssSpringBootConfigRegistry.get(key);
            if(CollectionUtils.isEmpty(targetValues)){
                return;
            }

            // 2.更新
            targetValues.forEach(pair -> {
                try {
                    CfssSpringBootConfigRegistry.bind(pair);
                } catch (Exception e) {
                    log.error("bind PropertiesToTarget error");
                }
            });
        });
    }

    /**
     * Check whether we should trigger the auto update or not
     * @param configChangeEvent
     * @param changedKey
     * @return
     */
    private boolean shouldTriggerAutoUpdate(ConfigChangeEvent configChangeEvent, String changedKey){
        ConfigChange configChange = configChangeEvent.getChange(changedKey);
        if (configChange.getChangeType() == PropertyChangeType.DELETED) {
            return true;
        }
        return Objects.equals(environment.getProperty(changedKey), configChange.getNewValue());
    }
}
